project(dmis-utility-components)
cmake_minimum_required( VERSION 2.8 )

set ( CMAKE_BUILD_TYPE Debug )
set ( LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../bin )
set ( EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/../../bin )
if( UNIX )
  add_definitions( -Wall -Wno-unused-function -Wno-write-strings )
endif()
include_directories ( ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} )

# change the following line to true if you have made changes to dmis.y
# and/or dmis.lex and need to regenerate the C++
set( REBUILD_PARSER false )

if( NOT EXISTS ${CMAKE_SOURCE_DIR}/dmisYACC.cc OR
    NOT EXISTS ${CMAKE_SOURCE_DIR}/dmisYACC.hh OR
    NOT EXISTS ${CMAKE_SOURCE_DIR}/dmisLex.cc )
  #missing files must be built
  set( REBUILD_PARSER true )
endif()


if( REBUILD_PARSER )
  FIND_PACKAGE(BISON)
  FIND_PACKAGE(FLEX)
endif()

if( BISON_FOUND AND FLEX_FOUND AND REBUILD_PARSER )
  message( "Will rebuild generated parser files with Flex and Bison." )

  # The files generated by bison and flex go in gen/, which is created by the compile
  # script, build-linuxSun.sh or build-windows.bat. The files in gen are copied/modified by
  # insertNamespace. The library target depends on the files insertNamespace creates.
  # Those files have the same names; to avoid confusing make, they use a different path.
  BISON_TARGET( dmisParser dmis.y ${PROJECT_BINARY_DIR}/gen/dmisYACC.cc )
  FLEX_TARGET( dmisScanner dmis.lex ${PROJECT_BINARY_DIR}/gen/dmisLex.cc )
  ADD_FLEX_BISON_DEPENDENCY( dmisScanner dmisParser )

  # recent versions of bison need a header to be included; older versions fail when it is included.
  # The following defines BISON_TWO_FOUR so it can be checked in the code generated from dmis.y
  # NOTE - this assumes that the behaviour change starts with 2.4.0
  string( COMPARE GREATER ${BISON_VERSION} 2.4 IS_BISON_TWENTYFOUR )
  if ( IS_BISON_TWENTYFOUR )
    message( "Bison 2.4 or later detected - will include header from dmisYACC.cc" )
    # FIXME how to make this sticky?!
    add_definitions( -DBISON_TWO_FOUR )
  endif()
  message( "Files generated by BISON: ${BISON_dmisParser_OUTPUTS}" )
  message( "Files generated by FLEX: ${FLEX_dmisScanner_OUTPUTS}" )

  #once the files are generated, portions of them must be wrapped in a namespace
  # build the insertNamespace executable to do so
  add_executable( insertNamespace insertNamespace.cc )
  get_target_property( insertNamespaceLoc insertNamespace LOCATION ) #full path to executable
  set( Parser_Scanner_Files ${CMAKE_SOURCE_DIR}/dmisYACC.cc
                            ${CMAKE_SOURCE_DIR}/dmisYACC.hh
                            ${CMAKE_SOURCE_DIR}/dmisLex.cc
                           )
  #if the insertNamespace binary is not ran in ${PROJECT_BINARY_DIR}, the following will fail
  #that probably won't happen, unless cmake changes drastically
  add_custom_command(OUTPUT ${Parser_Scanner_Files}
                     COMMAND ${insertNamespaceLoc}
                     COMMAND cmake -E copy dmisYACC.cc ${CMAKE_SOURCE_DIR}
                     COMMAND cmake -E copy dmisYACC.hh ${CMAKE_SOURCE_DIR}
                     COMMAND cmake -E copy dmisLex.cc ${CMAKE_SOURCE_DIR}
                     DEPENDS insertNamespace
                             ${BISON_dmisParser_OUTPUTS}
                             ${FLEX_dmisScanner_OUTPUTS}
                    )
else()
  if( REBUILD_PARSER )
    message( FATAL_ERROR "Error, tried to regenerate parser but cannot find Bison and/or Flex!")
  endif()
  message( "Will not run Flex or Bison (this is normal)." )
  #not regenerating, so set these vars to the names of the already-generated files
  set( Parser_Scanner_Files ${CMAKE_SOURCE_DIR}/dmisYACC.cc
                            ${CMAKE_SOURCE_DIR}/dmisYACC.hh
                            ${CMAKE_SOURCE_DIR}/dmisLex.cc
                           )
endif()

# binLinux/generateMore writes src/assignModuleSubAtts.cc
# which is then #included by src/makeLevels.cc
# When binLinux/makeLevels is executed, it writes src/levelsSet.cc
if( NOT EXISTS ${CMAKE_SOURCE_DIR}/assignModuleSubAtts.cc )
  add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/assignModuleSubAtts.cc
              COMMAND ../../bin/generateMore
              COMMAND cmake -E copy assignModuleSubAtts.cc ${CMAKE_SOURCE_DIR}
              )
endif()
if( NOT EXISTS ${CMAKE_SOURCE_DIR}/levelsSet.cc )
  add_executable( makeLevels makeLevels.cc assignModuleSubAtts.cc )
  get_target_property( makeLevelsLoc makeLevels LOCATION )
  add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/levelsSet.cc
              COMMAND ${makeLevelsLoc}
              COMMAND cmake -E copy levelsSet.cc ${CMAKE_SOURCE_DIR}/levelsSet.cc
              )
endif()


#creating a shared lib makes compilation faster, but then you have to
# use LD_LIBRARY_PATH or install the library in a standard location
# add_library( dmis SHARED dmis.cc dmis.hh ${Parser_Scanner_Files} )
add_library( dmis dmis.cc dmis.hh ${Parser_Scanner_Files} )

add_executable( dmisConformanceChecker
    dmisConformanceChecker.cc
    dmisConformanceCheckerDriver.cc
  )
target_link_libraries( dmisConformanceChecker dmis)

add_executable( dmisConformanceTester dmisConformanceTester.cc
                  dmisConformanceTesterDriver.cc )
target_link_libraries( dmisConformanceTester dmis)

add_executable( dmisConformanceRecorder dmisConformanceTester.cc dmisConformanceRecorderDriver.cc )
target_link_libraries( dmisConformanceRecorder dmis)

add_executable( dmisParser dmisParser.cc dmisParserDriver.cc )
target_link_libraries( dmisParser dmis)

add_executable( dmisTestFileReductor dmisTestFileReductor.cc )
